<?php

declare(strict_types=1);


namespace ImiApp\ApiServer\Api\Service;

use Imi\Bean\Annotation\Inherit;
use Imi\Config;
use ImiApp\ApiServer\Backend\Model\SoAttachment;
use ImiApp\ImiServer\AbstractModel;
use ImiApp\ImiServer\AbstractService;
use Imi\Bean\Annotation\Bean;
use ImiApp\ImiServer\Exception\ServiceException;
use Imi\Aop\Annotation\Inject;
use ImiApp\ImiServer\Service\Upload;
use Phpben\Imi\Auth\AuthManager;

use Imi\Server\Http\Message\UploadedFile;
use ImiApp\ApiServer\Api\Model\Attachment;




use Obs\ObsClient;
use Obs\ObsException;



use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;

/**
 * @Inherit
 * @Bean("ApiAttachment2Service")
 */
class Attachment2Service extends AbstractService
{
    /**
     * @var string
     */
    public $model = SoAttachment::class;

    /**
     * @var string
     */
    public $model2 = Attachment::class;

    /**
     * Auth
     * @Inject(name=AuthManager::class,args={"token"})
     */
    protected $auth;


    /**
     * @Inject(Upload::class)
     *
     * @var \ImiApp\ImiServer\Service\Upload
     */
    protected $upload;

    public function getParents(): array
    {
        $list = [['label' => '全部']];
        return array_merge($list, $this->model::query()->group("parent")->order('parent', 'desc')->fieldRaw("parent as label")->select()->getArray());
    }

    public function pull($files)
    {
        $file = $files['file'] ?? false;

        if (!$file) {
            $this->setError('未上传内容');
            return false;
        }
        $upload = $this->upload->pull($file);
        if (!$upload) {
            $this->setError($this->upload->getError());
            return false;
        }
        $data = array_merge([
            'type' => Config::get('@app.beans.Upload.save'),
            // 'admin_id' => $this->auth->id,
            'create_time' => time(),
        ], $upload);
        if ($row = $this->model::find(['filename' => $upload['filename']])) {
            $row->update($data);
        } else {
            $this->model::query()->insert($data);
        }

        //兼容fastadmin
        $sha1 = hash_file('sha1', '.' . $data['path']);
        $data = $this->compatible($data);
        if ($row2 = $this->model2::find(['sha1' => $sha1])) {
            $row2->update($data);
        } else {
            $this->model2::query()->insert($data);
        }
        $url = $this->oss($upload['path']);
        // $url = $this->oss('/public', '', $upload['path'],$file);
        return ['url' => str_replace('/public', '', $upload['path']), 'filename' => $upload['filename'], 'fullurl' => $upload['url'] ,'oss' => $url];
    }


    /**
     * 上传的图片加水印
     *
     * @return void
     */
    public function upload_water_image($files)
    {
        $file = $files['file'] ?? false;
        if (!$file) {
            $this->setError('未上传内容');
            return false;
        }
        // var_dump($file);
        $upload = $this->upload->pull($file);
        if (!$upload) {
            $this->setError($this->upload->getError());
            return false;
        }
        $data = array_merge([
            'type' => Config::get('@app.beans.Upload.save'),
            // 'admin_id' => $this->auth->id,
            'create_time' => time(),
        ], $upload);
        if ($row = $this->model::find(['filename' => $upload['filename']])) {
            $row->update($data);
        } else {
            $this->model::query()->insert($data);
        }

        //兼容fastadmin
        $sha1 = hash_file('sha1', '.' . $data['path']);
        $data = $this->compatible($data);
        if ($row2 = $this->model2::find(['sha1' => $sha1])) {
            $row2->update($data);
        } else {
            $this->model2::query()->insert($data);
        }

        $image = new \tp5er\Images\Image();     //QQ496631085
        $image->open('.' . $upload['path']);    //打开图片
        $width = $image->width(); // 返回图片的宽度
        $height = $image->height(); // 返回图片的高度
        // var_dump($width ,$height);

        $font = './public/uploads/font/1014be1a527bfbaa081b2810832e737e.ttc'; //水印字体路径
        $font_color = config('water_color') ?: '#3C3C1C66'; //水印字颜色
        $font_size = 10; //水印字体大小
        $text = config('water_text'); //水印文字

        $size = $this->get_text_size($text, $font, 30);
        $w = $size['w'];
        $h = $size['h'];
        for ($w_i = 0; $w_i <= $image->width() / $w; $w_i++) {
            for ($h_i = 0; $h_i <= $image->height() / $h; $h_i++) {
                //循环加入文字水印
                $image->text($text, $font, $font_size, $font_color, [$w_i * ($w + 20), $h_i * ($h + 20)], 0, 15);
            }
        }
        $image->save('.' . $upload['path']);    //保存文件

        $url = $this->oss($upload['path']);


        return ['url' => str_replace('/public', '', $upload['path']), 'filename' => $upload['filename'], 'fullurl' => $upload['url'], 'oss' => $url];
    }



    /**
     * 图像添加文字
     *
     * @param  string  $text   添加的文字
     * @param  string  $font   字体路径
     * @param  integer $size   字号
     *
     * @return $this
     * @throws ImageException
     */
    public function get_text_size($text, $font, $size)
    {
        if (!is_file($font)) {
            throw new ImageException("不存在的字体文件：{$font}");
        }
        //获取文字信息
        $info = imagettfbbox($size, 0, $font, $text);
        $minx = min($info[0], $info[2], $info[4], $info[6]);
        $maxx = max($info[0], $info[2], $info[4], $info[6]);
        $miny = min($info[1], $info[3], $info[5], $info[7]);
        $maxy = max($info[1], $info[3], $info[5], $info[7]);
        /* 计算文字初始坐标和尺寸 */
        $x = $minx;
        $y = abs($miny);
        $w = $maxx - $minx;
        $h = $maxy - $miny;
        return ['w' => $w, 'h' => $h];
    }


    public function compatible($data)
    {

        $getimagesize = getimagesize('.' . $data['path']);
        $params = array(
            // 'admin_id'    => (int)session('admin.id'),
            'user_id'     => $this->auth->user()->id,
            'store_id' => 0,
            'filename'    => $data['filename'],
            'filesize'    => $data['size'],
            'imagewidth'  => $getimagesize[0],
            'imageheight' => $getimagesize[1],
            'imagetype'   => $data['extension'],
            'imageframes' => 0,
            'mimetype'    => $data['mediatype'],
            'url'         => str_replace('/public', '', $data['path']),
            'uploadtime'  => $data['create_time'],
            'storage'     => $data['type'],
            'sha1'        => hash_file('sha1', '.' . $data['path']),
            'extparam'    => '',
            'updatetime' => $data['create_time'],
            'createtime' => $data['create_time'],
        );


        return $params;
    }


    public function _before_delete(&$ids)
    {
        foreach ($ids as $k => $id) {
            $path = $this->model::find($id);
            if (!$path) {
                unset($ids[$k]);
                continue;
            }
            $this->upload->delete($path->toArray()['path']);
        }
    }


    // public function oss2($path)
    // {
    //     $ak = "e0de2b68a23147d8bcef68b228e2ac06"; //?
    //     $sk = "A6TKVK2XWQD62BPUDBZN"; //?
    //     // $endpoint = "http://obs.cn-north-9.myhuaweicloud.com";

    //     $endpoint = "pddds.obs.cn-north-9.myhuaweicloud.com";
    //     $domainId = ""; //?

    //     // 创建ObsClient实例
    //     $obsClient = new ObsClient([
    //         'key' => $ak,
    //         'secret' => $sk,
    //         'endpoint' => $endpoint, //'https://your-endpoint',
    //     ]);

    //     $obsClient->initLog([
    //         'FilePath' => './.runtime/logs', // 配置日志文件夹
    //         'FileName' => 'eSDK-OBS-PHP.log', // 配置日志文件名
    //         'MaxFiles' => 10, // 配置最大可保留的日志文件个数
    //         'Level' => 100  // 配置日志级别
    //     ]);

    //     $resp = $obsClient->putObject([
    //         'Bucket' => 'pddds',
    //         'Key' => 'objectname.png',
    //         'SourceFile' => $path  // localfile为待上传的本地文件路径，需要指定到具体的文件名
    //     ]);
    //     var_dump("RequestId", $resp['RequestId']);
    //     // 使用访问OBS
    //     // 关闭obsClient
    //     $obsClient->close();
    // }

    public function oss($path)
    {
        $ak = 'M7EU11YWNEWIVNIV8ULR';
        $sk = 'fuqB8Q0Ut6WPyY0FvhwYDP8z8dEZRK6A6RXEzSC6';
        $endpoint = 'https://obs.cn-north-9.myhuaweicloud.com:443';
        $bucketName = 'pddds';
        
        $signature = 'obs';

        $q_path = substr($path,0,7);
        // var_dump($q_path);
        if($q_path=='/public'){
          $url_path = substr($path,7);
        //   var_dump($path);
        }else{
            $url_path = $path;
        }
        $objectKey = trim($url_path,'/');

        $obsClient = ObsClient::factory([
            'key' => $ak,
            'secret' => $sk,
            'endpoint' => $endpoint,
            'socket_timeout' => 30,
            'connect_timeout' => 10,
            'signature' => $signature
        ]);

        $sampleFilePath = '.' . $path;
        $this->createSampleFile($sampleFilePath);

        /*
        * Claim a post object request
        */
        $formParams = [];
        if (strcasecmp($signature, 'obs') === 0) {
            $formParams['x-obs-acl'] = ObsClient::AclPublicRead;
        } else {
            $formParams['acl'] = ObsClient::AclPublicRead;
        }
        $formParams['content-type'] = 'text/plain';

        $res = $obsClient->createPostSignature(['Bucket' => $bucketName, 'Key' => $objectKey, 'Expires' => 3600, 'FormParams' => $formParams]);

        $formParams['key'] = $objectKey;
        $formParams['policy'] = $res['Policy'];

        if (strcasecmp($signature, 'obs') === 0) {
            $formParams['Accesskeyid'] = $ak;
        } else {
            $formParams['AWSAccesskeyid'] = $ak;
        }

        $formParams['signature'] = $res['Signature'];


        // var_dump("Creating object in browser-based post way\n\n");
        $boundary = '9431149156168';

        $buffers = [];
        $contentLength = 0;

        /*
        * Construct form data
        */
        $buffer = [];
        $first = true;
        foreach ($formParams as $key => $val) {
            if (!$first) {
                $buffer[] = "\r\n";
            } else {
                $first = false;
            }

            $buffer[] = "--";
            $buffer[] = $boundary;
            $buffer[] = "\r\n";
            $buffer[] = "Content-Disposition: form-data; name=\"";
            $buffer[] = strval($key);
            $buffer[] = "\"\r\n\r\n";
            $buffer[] = strval($val);
        }

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Construct file description
        */
        $buffer = [];

        $buffer[] = "\r\n";
        $buffer[] = "--";
        $buffer[] = $boundary;
        $buffer[] = "\r\n";
        $buffer[] = "Content-Disposition: form-data; name=\"file\"; filename=\"";
        $buffer[] = "myfile";
        $buffer[] = "\"\r\n";
        $buffer[] = "Content-Type: text/plain";
        $buffer[] = "\r\n\r\n";

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Construct file data
        */
        $buffer = [];

        $fp = fopen($sampleFilePath, 'r');
        if ($fp) {
            while (!feof($fp)) {
                $buffer[] = fgetc($fp);
            }
            fclose($fp);
        }

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;

        /*
        * Contruct end data
        */
        $buffer = [];
        $buffer[] = "\r\n--";
        $buffer[] = $boundary;
        $buffer[] = "--\r\n";

        $buffer = implode('', $buffer);
        $contentLength += strlen($buffer);
        $buffers[] = $buffer;


        $httpClient = new Client(['verify' => false]);
        $host = parse_url($endpoint)['host'];
        $host = $bucketName . '.' . $host;
        $url = 'https://' . $host . ':443';
        // var_dump('url', $url);
        $headers = ['Content-Length' => strval($contentLength), 'Content-Type' => 'multipart/form-data; boundary=' . $boundary];

        try {
            $response = $httpClient->request('POST', $url, ['body' => implode('', $buffers), 'headers' => $headers]);

            // var_dump('Post object successfully!');
            $response->getBody()->close();
        } catch (ClientException $ex) {
            // var_dump('Exception message:%s', $ex->getMessage());
        }

   
        return 'https://' . $host.'/'.$url_path;

        // $obsClient = ObsClient::factory([
        //     'key' => $ak,
        //     'secret' => $sk,
        //     'endpoint' => $endpoint,
        //     'socket_timeout' => 30,
        //     'connect_timeout' => 10
        // ]);

        // $obsClient->initLog([
        //     'FilePath' => './.runtime/logs', // 配置日志文件夹
        //     'FileName' => 'eSDK-OBS-PHP.log', // 配置日志文件名
        //     'MaxFiles' => 10, // 配置最大可保留的日志文件个数
        //     'Level' => 100  // 配置日志级别
        // ]);


    }

    public function deleteTempFile($sampleFilePath)
    {
        if (file_exists($sampleFilePath)) {
            unlink($sampleFilePath);
        };
    }


    public function createSampleFile($filePath)
    {
        if (file_exists($filePath)) {
            return;
        }
        $filePath = iconv('UTF-8', 'GBK', $filePath);
        if (is_string($filePath) && $filePath !== '') {
            $fp = null;
            $dir = dirname($filePath);
            try {
                if (!is_dir($dir)) {
                    mkdir($dir, 0755, true);
                }

                if (($fp = fopen($filePath, 'w'))) {

                    for ($i = 0; $i < 1000000; $i++) {
                        fwrite($fp, uniqid() . "\n");
                        fwrite($fp, uniqid() . "\n");
                        if ($i % 100 === 0) {
                            fflush($fp);
                        }
                    }
                }
            } finally {
                if ($fp) {
                    fclose($fp);
                }
            }
        }
    }
}
